package com.ss.android.common.callback;

import android.os.Looper;

import com.bytedance.common.utility.Logger;
import com.bytedance.common.utility.collection.WeakList;

import java.util.HashMap;
import java.util.Iterator;

public final class CallbackCenter {
    public static class TYPE {
        private final String mName;

        public TYPE(String arg1) {
            this.mName = arg1;
        }

        static String name(TYPE type) {
            return type.mName;
        }

        public boolean checkParams(Object[] arg2) {
            return true;
        }

        public boolean equals(Object that) {
            if (this == (TYPE) that) {
                return true;
            } else if (that != null && this.getClass() == that.getClass()) {
                return this.mName.equals(((TYPE) that).mName);
            } else {
                return false;
            }
        }

        public int hashCode() {
            return this.mName.hashCode();
        }
    }

    private static HashMap<String, WeakList<?>> sMap = new HashMap();
    private static boolean abortDispatch;

    public static void notifyCallback(TYPE type, Object[] params) {
        if (type != null) {
            if (!type.checkParams(params)) {
                Logger.throwException("type:" + TYPE.name(type) + "; params is not valid:" + params);
                return;
            }

            if (Looper.myLooper() != Looper.getMainLooper()) {
                Logger.throwException("must be in the main thread !");
                return;
            }

            WeakList weakList = sMap.get(TYPE.name(type));
            if (weakList != null && weakList.weakHashMap.size() != 0) {
                abortDispatch = false;
                Iterator iterator = weakList.iterator();
                while (iterator.hasNext()) {
                    SSCallback ssCallback = (SSCallback) iterator.next();
                    if (abortDispatch) {
                        return;
                    }

                    if (ssCallback == null) {
                        continue;
                    }

                    try {
                        ssCallback.onCallback(params);
                    } catch (Exception exception) {
                        if (!Logger.debug()) {
                            exception.printStackTrace();
                            continue;
                        }
                        Logger.throwExceptionInDebug(exception);
                    }
                }
            }
        }
    }

    public static void addCallback(TYPE type, SSCallback callback) {
        WeakList weakList;
        if (type != null && callback != null) {
            weakList = sMap.get(TYPE.name(type));
            if (weakList == null) {
                weakList = new WeakList();
                sMap.put(TYPE.name(type), weakList);
            }
            weakList.add(callback);
        }
    }

    public static void abortDispatch() {
        abortDispatch = true;
    }

    public static void removeCallback(TYPE type, SSCallback callback) {
        if (type != null && callback != null) {
            WeakList weakList = sMap.get(TYPE.name(type));
            if (weakList != null) {
                weakList.remove(callback);
            }
        }
    }
}

